package pl.iachoo.ctl.tabory.ui.editors.compositions.composites;

import java.util.List;

import org.apache.log4j.Logger;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.SectionPart;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

import pl.iachoo.ctl.tabory.dao.hibernate.services.ServiceManager;
import pl.iachoo.ctl.tabory.dao.hibernate.vo.CompositionVO;
import pl.iachoo.ctl.tabory.ui.editors.compositions.CompositionSelection;
import pl.iachoo.ctl.tabory.ui.properties.Messages;
import pl.iachoo.ctl.tabory.ui.selection.ISelectionListener;
import pl.iachoo.ctl.tabory.ui.selection.ISelectionProvider;

public class CompositionTableSectionPart extends SectionPart implements
		ISelectionProvider<CompositionSelection> {

	private final Logger logg = Logger
			.getLogger(CompositionTableSectionPart.class);

	private String compositeName;
	private Table table;
	private TableViewer tableViewer;
	private Section filterSection;
	private ToolItem toolItemNew;
	private ToolItem toolItemEdit;
	private ToolItem toolItemDelete;
	private Composite composite;
	private Text filterCompositionName;

	private CompositionSelection selection;
	private ISelectionListener<CompositionSelection> selectionListener;

	/**
	 * Create the SectionPart.
	 * 
	 * @param parent
	 * @param toolkit
	 * @param style
	 */
	public CompositionTableSectionPart(Composite parent, FormToolkit toolkit,
			String compositeName) {
		super(parent, toolkit, Section.TITLE_BAR);
		this.compositeName = compositeName;
		createClient(getSection(), toolkit);
		initActions();
	}

	/**
	 * Fill the section.
	 */
	private void createClient(Section section, FormToolkit toolkit) {
		section.setText(compositeName);
		Composite container = toolkit.createComposite(section);

		ToolBar toolBar = new ToolBar(section, SWT.FLAT | SWT.HORIZONTAL);
		toolItemNew = new ToolItem(toolBar, SWT.FLAT);
		toolItemNew.setImage(PlatformUI.getWorkbench().getSharedImages()
				.getImage(ISharedImages.IMG_TOOL_NEW_WIZARD));
		toolItemNew.setToolTipText(Messages.getString("common.addnew"));
		toolItemEdit = new ToolItem(toolBar, SWT.PUSH);
		toolItemEdit.setImage(PlatformUI.getWorkbench().getSharedImages()
				.getImage(ISharedImages.IMG_TOOL_COPY));
		toolItemEdit.setToolTipText(Messages.getString("common.edit"));
		toolItemDelete = new ToolItem(toolBar, SWT.PUSH);
		toolItemDelete.setImage(PlatformUI.getWorkbench().getSharedImages()
				.getImage(ISharedImages.IMG_TOOL_DELETE));
		toolItemDelete.setToolTipText(Messages.getString("common.delete"));
		toolkit.paintBordersFor(toolBar);
		section.setTextClient(toolBar);

		section.setClient(container);
		container.setLayout(new GridLayout(1, false));

		tableViewer = new TableViewer(container, SWT.BORDER
				| SWT.FULL_SELECTION);
		tableViewer.setSorter(new Sorter());
		table = tableViewer.getTable();
		table.setHeaderVisible(true);
		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		toolkit.paintBordersFor(table);

		TableViewerColumn tableViewerColumn = new TableViewerColumn(
				tableViewer, SWT.NONE);
		TableColumn tblclmnNewColumn = tableViewerColumn.getColumn();
		tblclmnNewColumn.setWidth(120);
		tblclmnNewColumn.setText(Messages.getString("compositions.table.col0"));
		tableViewer.setLabelProvider(new TableLabelProvider());
		tableViewer.setContentProvider(new ContentProvider());

		filterSection = toolkit.createSection(container, Section.TWISTIE
				| Section.TITLE_BAR);
		filterSection.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
				false, 1, 1));
		toolkit.paintBordersFor(filterSection);
		filterSection.setText(Messages.getString("common.filter"));

		composite = toolkit.createComposite(filterSection, SWT.NONE);
		toolkit.paintBordersFor(composite);
		filterSection.setClient(composite);
		composite.setLayout(new GridLayout(2, false));

		toolkit.createLabel(
				composite,
				Messages.getString("compositions.table.filter.compositionname"),
				SWT.NONE);

		filterCompositionName = new Text(composite, SWT.NONE);
		filterCompositionName.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER,
				true, false, 1, 1));
		toolkit.adapt(filterCompositionName, true, true);
	}

	private void initActions() {
		toolItemNew.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				performNewItemAction(e);
			}

		});

		toolItemEdit.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				performItemEditAction(e);
			}
		});

		toolItemDelete.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				performItemDeleteAction(e);
			}
		});

		tableViewer
				.addSelectionChangedListener(new ISelectionChangedListener() {

					@Override
					public void selectionChanged(SelectionChangedEvent e) {
						performTableSelection(e);
					}
				});
	}

	protected void performTableSelection(SelectionChangedEvent e) {
		CompositionVO composition = (CompositionVO) (((StructuredSelection) e
				.getSelection()).getFirstElement());
		try {
			composition = ServiceManager.getCompositionService()
					.getComposition(composition.getId());
		} catch (Exception ex) {
			logg.error(ex.getMessage(), ex);
		}
		selection.setSelectedComposition(composition);
		selectionListener.selectionChanged(selection);
	}

	protected void performItemDeleteAction(SelectionEvent e) {
		throw new IllegalAccessError("not yet implemented");
	}

	protected void performItemEditAction(SelectionEvent e) {
		throw new IllegalAccessError("not yet implemented");
	}

	protected void performNewItemAction(SelectionEvent e) {
		selection.setEditing(false);
		selection.setNew(true);
		selection.setSelectedComposition(null);
		selectionListener.selectionChanged(selection);
		setEnabled(false);
	}

	private void setEnabled(boolean isEnabled) {
		table.setEnabled(isEnabled);
		toolItemDelete.setEnabled(isEnabled);
		toolItemEdit.setEnabled(isEnabled);
		toolItemNew.setEnabled(isEnabled);
		refreshActionStatus();
	}

	private void refreshActionStatus() {
		if (selection == null
				|| (selection != null && selection.getSelectedComposition() == null)) {
			toolItemDelete.setEnabled(false);
			toolItemEdit.setEnabled(false);
			toolItemNew.setEnabled(true);
		} else {
			toolItemDelete.setEnabled(true);
			toolItemEdit.setEnabled(true);
			toolItemNew.setEnabled(true);
		}
	}

	@Override
	public CompositionSelection getSelection() {
		return this.selection;
	}

	@Override
	public void setSelection(CompositionSelection selection) {
		this.selection = selection;
		if (selection.getListComposition() != null) {
			tableViewer.setInput(selection.getListComposition());
			table.setSelection(selection.getListComposition().indexOf(
					selection.getSelectedComposition()));
		}
		setEnabled(!selection.isEditing());
	}

	@Override
	public void addSelectionListener(
			ISelectionListener<CompositionSelection> listner) {
		this.selectionListener = listner;

	}

	@Override
	public void removeSelectionListener(
			ISelectionListener<CompositionSelection> listner) {
		this.selectionListener = null;
	}

	private static class Sorter extends ViewerSorter {

		public int compare(Viewer viewer, Object e1, Object e2) {
			CompositionVO composition1 = (CompositionVO) e1;
			CompositionVO composition2 = (CompositionVO) e2;
			return composition1.getInternalId().compareTo(
					composition2.getInternalId());
		}
	}

	private class TableLabelProvider extends LabelProvider implements
			ITableLabelProvider {

		public Image getColumnImage(Object element, int columnIndex) {
			return null;
		}

		public String getColumnText(Object element, int columnIndex) {
			CompositionVO composition = (CompositionVO) element;
			switch (columnIndex) {
			case 0:
				return composition.getInternalId();
			default:
				return "--";
			}
		}
	}

	private static class ContentProvider implements IStructuredContentProvider {

		@SuppressWarnings("unchecked")
		public Object[] getElements(Object inputElement) {
			List<CompositionVO> list = (List<CompositionVO>) inputElement;
			return list.toArray();
		}

		public void dispose() {
		}

		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}
	}

}
